home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 1833 / 1833.xpi / modules / yoonoSidebarService.js < prev    next >
Text File  |  2009-12-16  |  11KB  |  319 lines

  1. var EXPORTED_SYMBOLS = ["YOONO_SIDEBAR"];
  2.  
  3. Components.utils.import("resource://yoono/yoonoLog.js");
  4.  
  5. // This component handles sidebar related stuff
  6.  
  7.  
  8. const CI = Components.interfaces;
  9. const CL = Components.classes;
  10.  
  11. const WMED = CL['@mozilla.org/appshell/window-mediator;1'].getService(CI.nsIWindowMediator);
  12. const SCRIPT = CL["@mozilla.org/moz/jssubscript-loader;1"].getService(CI.mozIJSSubScriptLoader);
  13. const PREFSSERVICE = CL["@mozilla.org/preferences-service;1"].getService(CI.nsIPrefService);
  14. const PREFS = PREFSSERVICE.getBranch("extensions.yoono.");
  15.  
  16. const MARK_SELECTION_START = '\u200B\u200B\u200B\u200B\u200B';
  17. const MARK_SELECTION_END = '\u200B\u200B\u200B\u200B\u200B';
  18.  
  19.  
  20. var navigator = {userAgent: ""}; // prototype
  21.  
  22. // fake document object to supply mandatory methods
  23. /*
  24. var document = {
  25.   implementation: {
  26.     createDocument : function() {
  27.       var doc = CL["@mozilla.org/xml/xml-document;1"].createInstance();
  28.       doc.QueryInterface(CI.nsIDOMDocument);
  29.       return(doc);
  30.     }
  31.   }
  32. };
  33. */
  34. var document = null;
  35.  
  36. // Use the evil hack of the hidden window
  37. var window = null;
  38. var navigator = null;
  39. var Node = null;
  40. var Element = null;
  41. var XMLDocument = null;
  42. var DOMParser = null;
  43. var XMLSerializer = null;
  44. var XMLHttpRequest = null;
  45. var Document = null;
  46. var Event = null;
  47. var HTMLElement = null;
  48.  
  49. function alert(msg) {
  50.   return(window.alert(msg));
  51. }
  52.  
  53. /*
  54. function mkTimer(handler, delay, type) {
  55.   var timer = CL['@mozilla.org/timer;1'].createInstance(CI.nsITimer);
  56.   var obs = {
  57.     notify: function() {handler.call();}
  58.   };
  59.   timer.initWithCallback(obs, delay , type);
  60. }
  61.  
  62. function setInterval(handler, delay) {
  63.   return(mkTimer(handler, delay, CI.nsITimer.TYPE_REPEATING_PRECISE));
  64. }
  65.  
  66. function setTimeout(handler, delay) {
  67.   return(mkTimer(handler, delay, CI.nsITimer.TYPE_ONE_SHOT));
  68. }
  69.  
  70. function clearTimeout(timer) {
  71.   timer.cancel();
  72. }
  73. */
  74. function setInterval(handler, delay) {
  75.   return(window.setInterval(handler, delay));
  76. }
  77. function setTimeout(handler, delay) {
  78.   return(window.setTimeout(handler, delay));
  79. }
  80. function clearTimeout(timer) {
  81.   return(window.clearTimeout(timer));
  82. }
  83. function clearInterval(timer) {
  84.   return(window.clearInterval(timer));
  85. }
  86.  
  87.  
  88.  
  89. // SidebarComponent : le composant en lui meme
  90. function SidebarComponent() {
  91.   // objet magique qui permet l appel depuis le chrome
  92.   this.wrappedJSObject = this;
  93.   this.started = false;
  94.   this._started = false;
  95.   this.memoMgr = null;
  96.   this.eventMgr = null;
  97.   this.UTF8_MD5 = null;
  98.   this.serializer = null;
  99.  
  100.   this.init = function(yoono_cmpt) {
  101.     if(this._started) return;
  102.     this._started = true;
  103.     try {
  104.       window = Components.classes["@mozilla.org/appshell/appShellService;1"]
  105.          .getService(Components.interfaces.nsIAppShellService)
  106.          .hiddenDOMWindow;
  107.     } catch(e) {
  108.     }
  109.     // Some platforms may not have a hiddenDOMWindow...
  110.     if(!window) {
  111.       window = WMED.getMostRecentWindow("navigator:browser");
  112.     }
  113.  
  114.     Node = window.Node;
  115.     Element = window.Element;
  116.     XMLDocument = window.XMLDocument;
  117.     DOMParser = window.DOMParser;
  118.     XMLSerializer = window.XMLSerializer;
  119.     this.serializer = new XMLSerializer();
  120.     XMLHttpRequest = window.XMLHttpRequest;
  121.     // MemoMgr needs to access navigator for the locale
  122.     navigator = window.navigator;
  123.  
  124.     Document = window.Document;
  125.     Event = window.Event;
  126.     HTMLElement = window.HTMLElement;
  127.  
  128.     document = CL["@mozilla.org/xml/xml-document;1"].createInstance();
  129.     document.QueryInterface(CI.nsIDOMDocument);
  130.  
  131.     try  {
  132.       // ne s'execute qu'une seule fois par session
  133.       if (this.started) {
  134.         return;
  135.       }
  136.       YOONO_LOG.debug('Initializing YOONO_SIDEBAR');
  137.       this.started = true;
  138.       this.yoono_cmpt = yoono_cmpt;
  139.     } catch(e) {
  140.       YOONO_LOG.error('YOONO_SIDEBAR.init: ' + e  + '\n' + e.stack);
  141.     }
  142.   };
  143.  
  144.   this.loadScript = function(file) {
  145.     YOONO_LOG.debug('SidebarComponent.loadScript: Loading ' + file);
  146.     try {
  147.       SCRIPT.loadSubScript(file);
  148.     } catch(aError){
  149.       YOONO_LOG.error('SidebarComponent.loadScript : Loading ' + file + ' failed : '+aError);
  150.       throw aError;
  151.     }
  152.   };
  153.  
  154.   this.getMemoMgr = function(methods) {
  155.     try {
  156.       if(!this.memoMgr) {
  157.         SCRIPT.loadSubScript('chrome://yoonosb/content/js/yoono/memo/FFMemoLoader.js');
  158.         // This method is defined in the script loaded above
  159.         loadMemoScriptsInFirefox(this);
  160.         this.memoMgr = new MemoMgr();
  161.       }
  162.  
  163.       var userData = this.yoono_cmpt.getUserCredential();
  164.       var login = null;
  165.       var password = null;
  166.       if(userData) {
  167.         if(userData.anonymous) {
  168.           login = userData.userId;
  169.           password = '';
  170.         } else {  
  171.           login = userData.login;
  172.           password = userData.password;
  173.         }
  174.       }
  175.  
  176.       // Initialize the MemoMgr with the user data
  177.       this.memoMgr.init(login, password, methods);
  178.     } catch(e) {
  179.       YOONO_LOG.exception(e);
  180.     }
  181.     return(this.memoMgr);
  182.   };
  183.  
  184.   ////////////////////////////////////////////////////////////////////////////////
  185.   // Get container with marked selection 
  186.   this.getContainerForSelection = function(selection) {
  187.     var range = selection.getRangeAt(0);
  188.     var ancestorContainer = range.commonAncestorContainer;
  189.     var doc = ancestorContainer.ownerDocument;
  190.  
  191.     var startContainer = range.startContainer;
  192.     var endContainer = range.endContainer;
  193.     var startOffset = range.startOffset;
  194.     var endOffset = range.endOffset;
  195.  
  196.     // let the ancestor be an element
  197.     if (ancestorContainer.nodeType == ancestorContainer.TEXT_NODE ||
  198.         ancestorContainer.nodeType == ancestorContainer.CDATA_SECTION_NODE)
  199.       ancestorContainer = ancestorContainer.parentNode;
  200.  
  201.     // for selectAll, let's use the entire document, including <html>...</html>
  202.     // @see DocumentViewerImpl::SelectAll() for how selectAll is implemented
  203.     try {
  204.       if (ancestorContainer == doc.body)
  205.         ancestorContainer = doc.documentElement;
  206.     } catch (e) { }
  207.  
  208.     // each path is a "child sequence" (a.k.a. "tumbler") that
  209.     // descends from the ancestor down to the boundary point
  210.     var startPath = this.getPath(ancestorContainer, startContainer);
  211.     var endPath = this.getPath(ancestorContainer, endContainer);
  212.  
  213.     // clone the fragment of interest and reset everything to be relative to it
  214.     // note: it is with the clone that we operate/munge from now on
  215.     ancestorContainer = ancestorContainer.cloneNode(true);
  216.     startContainer = ancestorContainer;
  217.     endContainer = ancestorContainer;
  218.  
  219.     // Only bother with the selection if it can be remapped. Don't mess with
  220.     // leaf elements (such as <isindex>) that secretly use anynomous content
  221.     // for their display appearance.
  222.     var canDrawSelection = ancestorContainer.hasChildNodes();
  223.     if (canDrawSelection) {
  224.       var i;
  225.       for (i = startPath ? startPath.length-1 : -1; i >= 0; i--) {
  226.         startContainer = startContainer.childNodes.item(startPath[i]);
  227.       }
  228.       for (i = endPath ? endPath.length-1 : -1; i >= 0; i--) {
  229.         endContainer = endContainer.childNodes.item(endPath[i]);
  230.       }
  231.  
  232.       // add special markers to record the extent of the selection
  233.       // note: |startOffset| and |endOffset| are interpreted either as
  234.       // offsets in the text data or as child indices (see the Range spec)
  235.       // (here, munging the end point first to keep the start point safe...)
  236.       var tmpNode;
  237.       if (endContainer.nodeType == endContainer.TEXT_NODE ||
  238.           endContainer.nodeType == endContainer.CDATA_SECTION_NODE) {
  239.         // do some extra tweaks to try to avoid the view-source output to look like
  240.         // ...<tag>]... or ...]</tag>... (where ']' marks the end of the selection).
  241.         // To get a neat output, the idea here is to remap the end point from:
  242.         // 1. ...<tag>]...   to   ...]<tag>...
  243.         // 2. ...]</tag>...  to   ...</tag>]...
  244.         if ((endOffset > 0 && endOffset < endContainer.data.length) ||
  245.             !endContainer.parentNode || !endContainer.parentNode.parentNode)
  246.           endContainer.insertData(endOffset, MARK_SELECTION_END);
  247.         else {
  248.           tmpNode = doc.createTextNode(MARK_SELECTION_END);
  249.           endContainer = endContainer.parentNode;
  250.           if (endOffset == 0)
  251.             endContainer.parentNode.insertBefore(tmpNode, endContainer);
  252.           else
  253.             endContainer.parentNode.insertBefore(tmpNode, endContainer.nextSibling);
  254.         }
  255.       }
  256.       else {
  257.         tmpNode = doc.createTextNode(MARK_SELECTION_END);
  258.         endContainer.insertBefore(tmpNode, endContainer.childNodes.item(endOffset));
  259.       }
  260.  
  261.       if (startContainer.nodeType == startContainer.TEXT_NODE ||
  262.           startContainer.nodeType == startContainer.CDATA_SECTION_NODE) {
  263.         // do some extra tweaks to try to avoid the view-source output to look like
  264.         // ...<tag>[... or ...[</tag>... (where '[' marks the start of the selection).
  265.         // To get a neat output, the idea here is to remap the start point from:
  266.         // 1. ...<tag>[...   to   ...[<tag>...
  267.         // 2. ...[</tag>...  to   ...</tag>[...
  268.         if ((startOffset > 0 && startOffset < startContainer.data.length) ||
  269.             !startContainer.parentNode || !startContainer.parentNode.parentNode ||
  270.             startContainer != startContainer.parentNode.lastChild)
  271.           startContainer.insertData(startOffset, MARK_SELECTION_START);
  272.         else {
  273.           tmpNode = doc.createTextNode(MARK_SELECTION_START);
  274.           startContainer = startContainer.parentNode;
  275.           if (startOffset == 0)
  276.             startContainer.parentNode.insertBefore(tmpNode, startContainer);
  277.           else
  278.             startContainer.parentNode.insertBefore(tmpNode, startContainer.nextSibling);
  279.         }
  280.       }
  281.       else {
  282.         tmpNode = doc.createTextNode(MARK_SELECTION_START);
  283.         startContainer.insertBefore(tmpNode, startContainer.childNodes.item(startOffset));
  284.       }
  285.     }
  286.  
  287.     return ancestorContainer;
  288.   };
  289.  
  290.   ////////////////////////////////////////////////////////////////////////////////
  291.   // helper to get a path like FIXptr, but with an array instead of the "tumbler" notation
  292.   // see FIXptr: http://lists.w3.org/Archives/Public/www-xml-linking-comments/2001AprJun/att-0074/01-NOTE-FIXptr-20010425.htm
  293.   this.getPath = function(ancestor, node) {
  294.     var n = node;
  295.     var p = n.parentNode;
  296.     if (n == ancestor || !p)
  297.       return null;
  298.     var path = new Array();
  299.     if (!path)
  300.       return null;
  301.     do {
  302.       for (var i = 0; i < p.childNodes.length; i++) {
  303.         if (p.childNodes.item(i) == n) {
  304.           path.push(i);
  305.           break;
  306.         }
  307.       }
  308.       n = p;
  309.       p = n.parentNode;
  310.     } while (n != ancestor && p);
  311.     return path;
  312.   };
  313.  
  314.   
  315. }
  316.  
  317.  
  318. var YOONO_SIDEBAR = new SidebarComponent();
  319.